
export class EventProcessor {
    handlers: any = {};
    supportEvent: any = {};

    private _addListener (eventName: string, handler: Function, target: any, isOnce = false) {
        let objHandler = { handler: handler, target: target, isOnce: isOnce };
        let handlerList = this.handlers[eventName];
        if (!handlerList) {
            handlerList = [];
            this.handlers[eventName] = handlerList;
        }

        for (let i = 0; i < handlerList.length; i++) {
            if (!handlerList[i]) {
                handlerList[i] = objHandler;
                return i;
            }
        }

        handlerList.push(objHandler);

        return handlerList.length;
    }

    once (eventName: string, handler: Function, target: any) {
        this._addListener(eventName, handler, target, true);
    }

    on (eventName: string, handler: Function, target: any) {
        this._addListener(eventName, handler, target, false);
    }

    off (eventName: string, handler: Function, target: any) {
        var handlerList = this.handlers[eventName];

        if (!handlerList) {
            return;
        }

        for (var i = 0; i < handlerList.length; i++) {
            var oldObj = handlerList[i];
            if (oldObj.handler === handler && (!target || target === oldObj.target)) {
                handlerList.splice(i, 1);
                break;
            }
        }
    }

    dispatchEvent (eventName: string/**/, ...args: any) {
        // if (this.supportEvent !== null && !this.supportEvent.hasOwnProperty(eventName)) {
        //     cc.error("please add the event into clientEvent.js");
        //     return;
        // }

        let handlerList = this.handlers[eventName];

        let arrArgs = [];
        for (let i = 1; i < arguments.length; i++) {
            arrArgs.push(arguments[i]);
        }

        if (!handlerList) {
            return;
        }

        let cloneList = handlerList.slice(); //避免回调的时候会出现把函数从handlerList中移除
        for (let i = 0; i < cloneList.length; i++) {
            let objHandler = cloneList[i];
            if (objHandler.handler) {
                objHandler.handler.apply(objHandler.target, arrArgs);
            }

            if (objHandler.isOnce) {
                //派发完后，需要移除掉
                cloneList.splice(i, 1);
                i--;
            }
        }
    }

    setSupportEventList (arrSupportEvent: string[]) {
        if (!(arrSupportEvent instanceof Array)) {
            console.error("supportEvent was not array");
            return false;
        }

        this.supportEvent = {};
        for (var i in arrSupportEvent) {
            var eventName = arrSupportEvent[i];
            this.supportEvent[eventName] = i;
        }


        return true;
    }

}


export class ClientEvent {
    static _eventProcessor = new EventProcessor();

    //===================== 全局事件 =======================
    public static on (eventName: string, handler: Function, target: any) {
        this._eventProcessor.on(eventName, handler, target);
    }

    public static off (eventName: string, handler: Function, target: any) {
        this._eventProcessor.off(eventName, handler, target);
    }

    public static dispatchEvent (eventName: string, ...args: any) {
        this._eventProcessor.dispatchEvent(eventName, ...args);
    }
}
